package com.jprocms.module.cms.util;

import cn.hutool.core.lang.Assert;
import com.jpro.framework.common.util.cache.CacheUtils;
import com.jpro.framework.common.util.servlet.ServletUtils;
import com.jpro.framework.security.core.LoginUser;
import com.jpro.framework.security.core.util.SecurityFrameworkUtils;
import com.jprocms.module.cms.controller.admin.site.dto.SiteQueryDto;
import com.jprocms.module.cms.dal.dataobject.site.SiteDO;
import com.jprocms.module.cms.service.site.SiteService;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;
import java.util.function.Function;

/**
 * @author jprocms
 */
public class CmsContextUtil {


    public static final String SITE_PARAM = "jprocms-site-id";
    public static final String INTRANET_PREFIX = "/inner/";
    public static final String SITE_PATH_PARAM = "path";
    private static ThreadLocal<SiteDO> SITE_HOLDER = new ThreadLocal<>();
    /**
     * 是否pc访问线程变量
     */
    private static final ThreadLocal<Boolean> IS_PC_HOLDER = new ThreadLocal<>();

    private static SiteService siteService;

    public static void setPc(boolean isPc) {
        IS_PC_HOLDER.set(isPc);
    }

    public static boolean isPc() {
        return IS_PC_HOLDER.get() != null && IS_PC_HOLDER.get();
    }

    public static void clearPc() {
        IS_PC_HOLDER.remove();
    }

    public static void setSite(SiteDO site) {
        SITE_HOLDER.set(site);
    }

    public static void resetSite() {
        SITE_HOLDER.remove();
    }

    public static SiteDO getSite() {
        return SITE_HOLDER.get();
    }

    public static Long getCurrSiteId() {
        return getSite().getId();
    }

    public static SiteDO getCurrentSite(Function<SiteQueryDto, SiteDO> function) {
        HttpServletRequest request = ServletUtils.getRequest();
        Assert.notNull(request);
        Assert.notNull(function);
        SiteQueryDto siteQueryDto = new SiteQueryDto();
        siteQueryDto.setSiteId(getSiteId(request));
        siteQueryDto.setPath(getPath(request));
        siteQueryDto.setDomain(getDomain(request));
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (loginUser != null) {
            Long curUserId = loginUser.getId();
            siteQueryDto.setUserId(curUserId);
        }
        return function.apply(siteQueryDto);
    }


    private static Long getSiteId(HttpServletRequest request) {
        String p = request.getHeader(SITE_PARAM);
        if (StringUtils.isBlank(p)) {
            p = request.getParameter(SITE_PARAM);
        }
        if (StringUtils.isNumeric(p)) {
            return Long.valueOf(p);
        }
        return null;
    }

    private static String getPath(HttpServletRequest request) {
        String p = request.getParameter(SITE_PATH_PARAM);
        String uri = request.getRequestURI();
        String ctx = request.getContextPath();
        if (StringUtils.isNoneBlank(ctx)) {
            uri = uri.substring(ctx.length());
        }
        // 移除开头的斜杠
        String normalizedPath = uri.startsWith("/") ? uri.substring(1) : uri;
        // 获取第一个路径段
        String firstPathSegment = normalizedPath.split("/")[0];
        //如果第一个路径段落匹配站点访问目录，则是内网访问 返回路径
        final Set<String> siteVisitPathCache = siteService.getSiteVisitPathCache();
        if (siteVisitPathCache.contains(firstPathSegment)) {
            p = firstPathSegment;
        }
        return p;
    }

    private static String getDomain(HttpServletRequest request) {
        return request.getServerName();
    }

    /**
     * 初始化方法，由Spring调用
     */
    public static void setSiteService(SiteService siteService) {
        CmsContextUtil.siteService = siteService;
    }

}
